package com.zzyl.nursing.service.impl;

import java.time.LocalDateTime;
import java.util.List;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.CodeGenerator;
import com.zzyl.common.utils.DateUtils;
import com.zzyl.common.utils.IDCardUtils;
import com.zzyl.common.utils.bean.BeanUtils;
import com.zzyl.nursing.domain.*;
import com.zzyl.nursing.dto.CheckInApplyDto;
import com.zzyl.nursing.dto.CheckInElderDto;
import com.zzyl.nursing.mapper.*;
import com.zzyl.nursing.vo.CheckInConfigVo;
import com.zzyl.nursing.vo.CheckInDetailVo;
import com.zzyl.nursing.vo.CheckInElderVo;
import com.zzyl.nursing.vo.ElderFamilyVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zzyl.nursing.service.ICheckInService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import springfox.documentation.spring.web.json.Json;

import java.util.Arrays;

/**
 * 入住Service业务层处理
 *
 * @author zoffy
 * @date 2025-07-25
 */
@Service
public class CheckInServiceImpl extends ServiceImpl<CheckInMapper, CheckIn> implements ICheckInService {
    @Autowired
    private CheckInMapper checkInMapper;
    @Autowired
    private ElderMapper elderMapper;
    @Autowired
    private BedMapper bedMapper;
    @Autowired
    private ContractMapper contractMapper;
    @Autowired
    private CheckInConfigMapper checkInConfigMapper;

    /**
     * 查询入住
     *
     * @param id 入住主键
     * @return 入住
     */
    @Override
    public CheckIn selectCheckInById(Long id) {
        return getById(id);
    }

    /**
     * 查询入住列表
     *
     * @param checkIn 入住
     * @return 入住
     */
    @Override
    public List<CheckIn> selectCheckInList(CheckIn checkIn) {
        return checkInMapper.selectCheckInList(checkIn);
    }

    /**
     * 新增入住
     *
     * @param checkIn 入住
     * @return 结果
     */
    @Override
    public int insertCheckIn(CheckIn checkIn) {
        return save(checkIn) ? 1 : 0;
    }

    /**
     * 修改入住
     *
     * @param checkIn 入住
     * @return 结果
     */
    @Override
    public int updateCheckIn(CheckIn checkIn) {
        return updateById(checkIn) ? 1 : 0;
    }

    /**
     * 批量删除入住
     *
     * @param ids 需要删除的入住主键
     * @return 结果
     */
    @Override
    public int deleteCheckInByIds(Long[] ids) {
        return removeByIds(Arrays.asList(ids)) ? 1 : 0;
    }

    /**
     * 删除入住信息
     *
     * @param id 入住主键
     * @return 结果
     */
    @Override
    public int deleteCheckInById(Long id) {
        return removeById(id) ? 1 : 0;
    }


    @Override
    public void apply(CheckInApplyDto dto) {
        try {
            //校验老人是否已经入住
            LambdaQueryWrapper<Elder> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Elder::getIdCardNo, dto.getCheckInElderDto().getIdCardNo())
                    .eq(Elder::getStatus, 0);
            Elder elder = elderMapper.selectOne(queryWrapper);
            if (ObjectUtils.isNotEmpty(elder)) {
                throw new BaseException("该老人已入住");
            }

            //更新床位状态为已入住
            Bed bed = bedMapper.selectById(dto.getCheckInConfigDto().getBedId());
            bed.setBedStatus(1);
            bedMapper.updateById(bed);
            //自增或更新老人
            elder = insertOrUpdateElder(dto.getCheckInElderDto(), bed);
            //新增签约办理(合同)
            String contractNo = "HT" + CodeGenerator.generateContractNumber();
            insertContract(contractNo, elder, dto);
            //新增入住信息
            CheckIn checkIn =insertCheckIn(dto,elder);
            //新增入住配置
            insertCheckInConfig(dto, checkIn);
        } catch (BaseException e) {
            throw new RuntimeException(e);
        }
    }

    private void insertCheckInConfig(CheckInApplyDto dto, CheckIn checkIn) {
        CheckInConfig checkInConfig = new CheckInConfig();
        //复制
        BeanUtils.copyProperties(dto.getCheckInConfigDto(), checkInConfig);
        checkInConfig.setCheckInId(checkIn.getId());
        //依旧没有sort_order字段,排序编号,默认0
        checkInConfigMapper.insert(checkInConfig);
    }


    private CheckIn insertCheckIn(CheckInApplyDto dto, Elder elder) {
        CheckIn checkIn = new CheckIn();
        checkIn.setElderName(elder.getName());
        checkIn.setElderId(elder.getId());
        checkIn.setIdCardNo(elder.getIdCardNo());
        checkIn.setStartDate(dto.getCheckInConfigDto().getStartDate());
        checkIn.setEndDate(dto.getCheckInConfigDto().getEndDate());
        checkIn.setNursingLevelName(dto.getCheckInConfigDto().getNursingLevelName());
        checkIn.setBedNumber(elder.getBedNumber());
        checkIn.setStatus(0);
        //保存老人家属配置.将dto里家属信息转换为json
        String jsonString = JSON.toJSONString(dto.getElderFamilyDtoList());
        //存放在remark字段
        checkIn.setRemark(jsonString);
        save(checkIn);

        return checkIn;
    }

    private void insertContract(String contractNo, Elder elder, CheckInApplyDto dto) {
        Contract contract = new Contract();
        BeanUtils.copyProperties(dto.getCheckInContractDto(), contract);
        contract.setContractNumber(contractNo);
        contract.setElderName(elder.getName());
        contract.setElderId(elder.getId());
        //开始时间结束时间从入住配置获取
        LocalDateTime startDate = dto.getCheckInConfigDto().getStartDate();
        LocalDateTime endDate = dto.getCheckInConfigDto().getEndDate();
        contract.setStartDate(startDate);
        contract.setEndDate(endDate);
        //设置状态,根据开始时间和结束时间
        if (startDate.isBefore(LocalDateTime.now())) {
            contract.setStatus(1);
        } else if (startDate.isBefore(LocalDateTime.now())) {
            contract.setStatus(0);
        } else if (startDate.isAfter(LocalDateTime.now()) && endDate.isAfter(LocalDateTime.now())) {
            contract.setStatus(2);
        } else if (endDate.isBefore(LocalDateTime.now())) {
            contract.setStatus(3);
        }
        //差一个sort_order字段,默认值为0,排序编号


        contractMapper.insert(contract);

    }

    private Elder insertOrUpdateElder(CheckInElderDto checkInElderDto, Bed bed) {
        Elder elder = new Elder();
        //属性拷贝
        BeanUtils.copyProperties(checkInElderDto, elder);
        elder.setStatus(1);
        elder.setBedId(bed.getId());
        elder.setBedNumber(bed.getBedNumber());
        //查询老人是否存在,在则修改,不在则新增
        LambdaQueryWrapper<Elder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Elder::getIdCardNo, checkInElderDto.getIdCardNo())
                .eq(Elder::getStatus, 1);
        Elder elder1 = elderMapper.selectOne(queryWrapper);
        if (ObjectUtils.isNotEmpty(elder1)) {
            elder.setId(elder1.getId());
            elderMapper.updateById(elder);
        } else {
            elder.setCreateTime(DateUtils.getNowDate());
            elderMapper.insert(elder);
        }
        return elder;
    }


    @Override
    public CheckInDetailVo detail(Long id) {
        //判断老人是否存在
        CheckIn checkIn = selectCheckInById(id);
        if (ObjectUtils.isEmpty(checkIn)) {
            throw new BaseException("该入住不存在老人");
        }
        CheckInDetailVo checkInDetailVo = new CheckInDetailVo();
        //1.查询checkInElderVo
        CheckInElderVo checkInElderVo = new CheckInElderVo();
         //1.1查询老人信息并赋值给CheckInDetailVo里的checkInElderVo
        Elder elder = elderMapper.selectById(checkIn.getElderId());
        BeanUtils.copyProperties(elder, checkInElderVo);
        //根据身份证号计算年龄
       // String idCardNo = checkInElderVo.getIdCardNo();
        int ageFromIDCard = IDCardUtils.getAgeFromIDCard(checkInElderVo.getIdCardNo());
        checkInElderVo.setAge(ageFromIDCard);
        checkInDetailVo.setCheckInElderVo(checkInElderVo);

        //2.查询elderFamilyVoList
         //2.2 将入住表里的remark进行JSON转换,elderFamilyVoList
        List<ElderFamilyVo> elderFamilyVoList = JSON.parseArray(checkIn.getRemark(), ElderFamilyVo.class);
        checkInDetailVo.setElderFamilyVoList(elderFamilyVoList);

        //3查询checkInConfigVo
        CheckInConfigVo checkInConfigVo = new CheckInConfigVo();
         //3.1将入住配置复制给checkInConfigVo
        //根据入住表id查询对应入住配置表
        LambdaQueryWrapper<CheckInConfig> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CheckInConfig::getCheckInId, checkIn.getId());
        CheckInConfig checkInConfig = checkInConfigMapper.selectOne(queryWrapper);
        BeanUtils.copyProperties(checkInConfig, checkInConfigVo);
        checkInDetailVo.setCheckInConfigVo(checkInConfigVo);
        //查询contract
        LambdaQueryWrapper<Contract> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(Contract::getElderId, checkIn.getElderId());
        Contract contract = contractMapper.selectOne(queryWrapper1);

        checkInDetailVo.setContract(contract);
        //将查询到的信息封装到CheckInDetailVo中并返回
        return checkInDetailVo;
    }

}
